package com.sujeet.learning.threads;

import java.util.Scanner;

public class Pallindrome {
	static String str = "nitin";
	static String str2 = "abexxeba";
	static boolean matched = true;
	static boolean latch = true;

	class MatchObject {
		private char l;
		private char r;
		private int matchCounter = 0;
		
		public void put(char c, boolean isLeft) {
			matchCounter++;
			if (isLeft) {
				l = c;
			} else {
				r = c;
			}
			if (matchCounter == 2) { // if left and right entries are added - time to compare
				if ((l != 0) && (r != 0)) {
					if (l != r) {
						matched = false;
						System.out.println("left = " + l + ", right= " + r + " =>mismatch");
					} else {
						System.out.println("left = " + l + ", right= " + r + " =>match");
					}
				}
				matchCounter=0; l=0;r=0; // after comparison clear the state for next set 
			}	
		}
	}

	public static void main(String[] args) {
		final Pallindrome pallindrome = new Pallindrome();
		final MatchObject mo = pallindrome.new MatchObject();
		Scanner scanner = new Scanner(System.in);
		String s = scanner.nextLine();
		final String taken = s;
		final double mp;
		int half = taken.length() / 2;
		int rem = taken.length() % 2;
		if (rem != 0) {
			mp = half; // odd no of characters
		} else {
			mp = half - 0.5; //even no of characters
		}

		System.out.println();
		
		// thread from left to midpoint
		Thread forward = new Thread(new Runnable() {
			public void run() {
				int i = 0;
				while(true) { // a for loop will simply wait, keep trying on the latch in a continuous loop
					try {
						if (matched && i < mp) {
						char l = taken.charAt(i);
						synchronized (mo) {
								if (latch) {
									mo.put(l, true);
									latch = false; i++;
									mo.notify();
								} else {
									mo.wait();
								}
							}
						} else {
							break; // break out if there is a mismatch or i steps over mp
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		});

		// thread from right to midpoint
		Thread backward = new Thread(new Runnable() {
			public void run() {
				int i = taken.length() - 1;
				while(true) { // a for loop will simply wait, keep trying on the latch in a continuous loop
					try {
						if (matched && i > mp) {
							char r = taken.charAt(i);
							synchronized (mo) {
									if (!latch) {
										mo.put(r, false);									
										latch = true; i--;
										mo.notify();
									} else {
										mo.wait();
									}
							}													
						} else {
							break; // break out if there is a mismatch or i steps over mp
						}
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		});

		forward.setName("forward");
		backward.setName("backward");
		forward.start();
		backward.start();

		try {
			// let both the threads finish to declare result
			forward.join();
			backward.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		System.out.println("Ques. Is " + s + " a Pallindrome? Ans. " + matched);
	}
}
